package com.cn.lp.export.server.entity;

import com.cn.lp.export.server.ExportResultCodes;
import com.cn.lp.export.server.base.context.ExportException;
import com.cn.lp.export.server.base.context.ExportExceptionCreator;
import com.cn.lp.export.server.base.context.IDCreator;
import com.cn.lp.export.server.controller.CreateExportTaskRequest;
import com.cn.lp.export.server.controller.CreateExportTaskResponse;
import com.cn.lp.export.server.controller.UploadExportDataRequest;
import com.cn.lp.export.server.entity.executor.ExportExecutor;
import com.cn.lp.export.server.entity.executor.ExportResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;

/**
 * 导出服务
 *
 * @author wuqirong
 * @date 2020-10-16
 * <p>
 * All rights Reserved, Designed www.xiao100.com
 */
@Service
public class ExportService {

    @Autowired
    private ExportTaskDao exportTaskDao;

    @Autowired
    private ExportSyncDataDao exportSyncDataDao;

    @Autowired
    private IDCreator<Long> idCreator;

    @Autowired
    private ExportExecutor exportExecutor;

    @Transactional(rollbackOn = Exception.class)
    public CreateExportTaskResponse createExportTask(CreateExportTaskRequest createRequest) {
        ExportResult result = exportExecutor.createResultUrl(createRequest);
        ExportTask exportTask = ExportTask.of(
            idCreator.createNext(ExportTask.class),
            createRequest.getExportFieldMap(),
            result.getResultName(),
            createRequest.getTotalNum(),
            result.getResultUrl()
        );
        exportTaskDao.save(exportTask);
        CreateExportTaskResponse response = new CreateExportTaskResponse();
        response.setTaskId(String.valueOf(exportTask.getId()));
        response.setResultUrl(result.getResultUrl());
        return response;
    }

    @Transactional(rollbackOn = Exception.class)
    public ExportStatus uploadExportData(UploadExportDataRequest uploadRequest) {
        long id = Long.parseLong(uploadRequest.getTaskId());
        ExportTask exportTask = exportTaskDao.findById(id)
            .orElseThrow(() -> ExportExceptionCreator.create(ExportResultCodes.TASK_NOT_EXIST, id));
        if (exportTask.getExportStatus() != ExportStatus.READY) {
            throw ExportExceptionCreator.create(ExportResultCodes.TASK_NOT_IN_READY, id);
        }
        exportTask.updateDataNum(uploadRequest.getDataNum());
        ExportSyncData syncData = ExportSyncData.of(
            idCreator.createNext(ExportTask.class),
            id,
            uploadRequest.getSort(),
            uploadRequest.getData()
        );
        exportSyncDataDao.save(syncData);
        if (exportTask.isFullData()) {
            exportTask.updateStatus(ExportStatus.RUNNING);
        }
        exportTaskDao.save(exportTask);
        return exportTask.getExportStatus();
    }

    @Transactional(rollbackOn = Exception.class)
    public void cancelTask(long taskId) {
        ExportTask exportTask = exportTaskDao.findById(taskId)
            .orElseThrow(() -> ExportExceptionCreator.create(ExportResultCodes.TASK_NOT_EXIST, taskId));
        exportTask.updateStatus(ExportStatus.CANCEL);
        exportSyncDataDao.deleteByTaskId(taskId);
    }
}
